From fc865b3912beb9b3768873afcc4d9b3be598214d Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Wed, 19 Aug 2009 14:23:30 +0100 Subject: [PATCH] AMD IOMMU: support "passthrough" and "no-intremap" parameters. Signed-off-by: Wei Wang --- xen/drivers/passthrough/amd/iommu_map.c | 8 +++++--- xen/drivers/passthrough/amd/pci_amd_iommu.c | 19 ++++++++++++++----- xen/include/asm-x86/hvm/svm/amd-iommu-proto.h | 3 ++- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/xen/drivers/passthrough/amd/iommu_map.c b/xen/drivers/passthrough/amd/iommu_map.c index ec06b194c9..3d051d4696 100644 --- a/xen/drivers/passthrough/amd/iommu_map.c +++ b/xen/drivers/passthrough/amd/iommu_map.c @@ -256,7 +256,7 @@ static void amd_iommu_set_page_directory_entry(u32 *pde, void amd_iommu_set_dev_table_entry(u32 *dte, u64 root_ptr, u64 intremap_ptr, u16 domain_id, u8 sys_mgt, u8 dev_ex, - u8 paging_mode) + u8 paging_mode, u8 valid, u8 int_valid) { u64 addr_hi, addr_lo; u32 entry; @@ -297,7 +297,8 @@ void amd_iommu_set_dev_table_entry(u32 *dte, u64 root_ptr, u64 intremap_ptr, set_field_in_reg_u32(0xB, entry, IOMMU_DEV_TABLE_INT_TABLE_LENGTH_MASK, IOMMU_DEV_TABLE_INT_TABLE_LENGTH_SHIFT, &entry); - set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, entry, + set_field_in_reg_u32(int_valid ? IOMMU_CONTROL_ENABLED : + IOMMU_CONTROL_DISABLED, entry, IOMMU_DEV_TABLE_INT_VALID_MASK, IOMMU_DEV_TABLE_INT_VALID_SHIFT, &entry); set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, entry, @@ -340,7 +341,8 @@ void amd_iommu_set_dev_table_entry(u32 *dte, u64 root_ptr, u64 intremap_ptr, set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, entry, IOMMU_DEV_TABLE_TRANSLATION_VALID_MASK, IOMMU_DEV_TABLE_TRANSLATION_VALID_SHIFT, &entry); - set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, entry, + set_field_in_reg_u32(valid ? IOMMU_CONTROL_ENABLED : + IOMMU_CONTROL_DISABLED, entry, IOMMU_DEV_TABLE_VALID_MASK, IOMMU_DEV_TABLE_VALID_SHIFT, &entry); dte[0] = entry; diff --git a/xen/drivers/passthrough/amd/pci_amd_iommu.c b/xen/drivers/passthrough/amd/pci_amd_iommu.c index ceee6009a5..7ab82d9912 100644 --- a/xen/drivers/passthrough/amd/pci_amd_iommu.c +++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c @@ -69,7 +69,7 @@ static void amd_iommu_setup_domain_device( void *dte; unsigned long flags; int req_id; - u8 sys_mgt, dev_ex; + u8 sys_mgt, dev_ex, valid = 1, int_valid = 1; struct hvm_iommu *hd = domain_hvm_iommu(domain); BUG_ON( !hd->root_table || !hd->paging_mode || !int_remap_table ); @@ -86,11 +86,16 @@ static void amd_iommu_setup_domain_device( sys_mgt = ivrs_mappings[req_id].dte_sys_mgt_enable; dev_ex = ivrs_mappings[req_id].dte_allow_exclusion; + if ( iommu_passthrough && (domain->domain_id == 0) ) + valid = 0; + if ( !iommu_intremap ) + int_valid = 0; + amd_iommu_set_dev_table_entry((u32 *)dte, page_to_maddr(hd->root_table), virt_to_maddr(int_remap_table), hd->domain_id, sys_mgt, dev_ex, - hd->paging_mode); + hd->paging_mode, valid, int_valid); invalidate_dev_table_entry(iommu, req_id); invalidate_interrupt_table(iommu, req_id); @@ -223,9 +228,13 @@ static int amd_iommu_domain_init(struct domain *domain) if ( domain->domain_id == 0 ) { unsigned long i; - /* setup 1:1 page table for dom0 */ - for ( i = 0; i < max_page; i++ ) - amd_iommu_map_page(domain, i, i); + + if ( !iommu_passthrough ) + { + /* setup 1:1 page table for dom0 */ + for ( i = 0; i < max_page; i++ ) + amd_iommu_map_page(domain, i, i); + } amd_iommu_setup_dom0_devices(domain); } diff --git a/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h b/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h index 6664fbaed2..9d1ef04097 100644 --- a/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h +++ b/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h @@ -68,7 +68,8 @@ void invalidate_all_iommu_pages(struct domain *d); /* device table functions */ void amd_iommu_set_dev_table_entry(u32 *dte, u64 root_ptr, u64 intremap_ptr, - u16 domain_id, u8 sys_mgt, u8 dev_ex, u8 paging_mode); + u16 domain_id, u8 sys_mgt, u8 dev_ex, u8 paging_mode, + u8 valid, u8 int_valid); int amd_iommu_is_dte_page_translation_valid(u32 *entry); void invalidate_dev_table_entry(struct amd_iommu *iommu, u16 devic_id); -- 2.30.2